// void, Obj This, point pt

bool b;
Unit this;
point ptOld, ptpos;

Sleep(rand(100)+30);
this = This.AsUnit();
if (.IsValid){ // leave parry mode at new command
	.SetParryMode(false);
	
	if(.hero.IsValid){
		if(.hero.HasItem("irage_battle")){
			Sleep(rand(200)+50);
			.AddCommand(true, "engage");
			return;
		} else if(.hero.HasItem("irage_battle_stand")){
			Sleep(rand(200)+50);
			.AddCommand(true, "stand_position");
			return;
		}
	}
	
	if(.item_count > 0){
		Item item;
		
		item = .FindItem("Terrain bonus I");
		if(item.IsValid)
			.RemoveItemsOfType("Terrain bonus I");
		else {
			item = .FindItem("Terrain bonus II");
			if(item.IsValid)
				.RemoveItemsOfType("Terrain bonus II");
			else {
				item = .FindItem("Terrain bonus III");
				if(item.IsValid)
					.RemoveItemsOfType("Terrain bonus III");
				else {
					item = .FindItem("Terrain bonus IV");
					if(item.IsValid)
						.RemoveItemsOfType("Terrain bonus IV");
				}
			}
		}
	}
}

if (This.AsHero().IsValid()) {
	if (This.AsHero().army.count() != 0) return;
}
ptpos = .posRH;
//pr("explore start");
//if the user gives an impassable or unreachable point for goto
while (1) {
//	pr("goto start");
	ptOld = .posRH;
	b = .Goto(pt, 0, 3000, true, -1);
	if (b) break; //reached the point
	if (.pos == ptOld) //not moved for a while
		break; //give up and recast to a new point
}

//if (.pos == ptOld) pr("cannot reach the start, begin from here");
//else pr("start reached, exploring");

while (1) {
//	pr("recast");
	pt = .GetUnexploredPoint(-1);
	if (pt.x == -1) break; //cannot go anywhere
	while (1) {
		//pr("going...");
		ptOld = .posRH;
		b = .Goto(pt, 0, 5000, true, -1);
		if (b) break;
		if (ptOld == .posRH)
			break; //stuck again :(
	}
//	if (b) pr("reached!"); else pr("stuck!");
}
//pr("explore end");
Sleep(rand(100)+30);
.AddCommand(false, "move", ptpos);
